package com.lvmama.pangolin.proces;


import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.lvmama.pangolin.HBaseOper.XCHBEntityOperation;
import com.lvmama.pangolin.common.Constant;
import com.lvmama.pangolin.common.DateUtil;
import com.lvmama.pangolin.common.RowkeyGenerator;
import com.lvmama.pangolin.common.StringTools;
import com.lvmama.pangolin.conf.ConfigManager;
import com.lvmama.pangolin.entity.ConvertTask;
import com.lvmama.pangolin.entity.RelevanceProduct;
import com.lvmama.pangolin.entity.RuleLevelModel;
import com.lvmama.pangolin.entity.Task_History;
import com.lvmama.pangolin.entity.xc.XCTicketCommodityItem;
import com.lvmama.pangolin.entity.xc.XCTicketCommodityPrice;
import com.lvmama.pangolin.entity.xc.XCTicketProductItem;
import com.lvmama.pangolin.entity.xc.XCTicket_Commodity;
import com.lvmama.pangolin.entity.xc.XCTicket_CommodityDetail;
import com.lvmama.pangolin.hbaseutil.HBaseUtils;
import com.lvmama.pangolin.service.RelevanceProductService;
import com.lvmama.pangolin.util.RuleUtil;
import com.lvmama.pangolin.xc.service.XCTicketCommPriceService;
import com.lvmama.pangolin.xc.service.XCTicketCommodityDetailService;
import com.lvmama.pangolin.xc.service.XCTicketCommodityItemsService;
import com.lvmama.pangolin.xc.service.XCTicketCommodityService;
import com.lvmama.pangolin.xc.service.XCTicketProductItemsService;
import com.lvmama.pangolin.xc.service.XCTicketProductNewService;
@Component
public class XCTicketDataProcess {
	/**  
	* @Title：TC_Data_Process.java
	* @Author:zhoutianqi
	* @Description:
	* @Date：2017年2月15日下午3:12:25  
	*/
	private Logger logger = Logger.getLogger(XCTicketDataProcess.class);
	@Autowired
	private XCTicketCommodityService commodityService;
	@Autowired
	private XCTicketCommodityDetailService detailService;
	@Autowired
	private XCTicketProductItemsService productItemsService;
	@Autowired
	private XCTicketProductNewService productNewService;
	@Autowired
	private XCTicketCommodityItemsService commodityItemsService;
	@Autowired
	private XCTicketCommPriceService commPriceService;
	@Autowired
	private RuleUtil ruleUtil;
	@Autowired
	private ConfigManager configManager;
	@Autowired
	private HBaseUtils hBaseUtil;
	@Autowired
	private XCHBEntityOperation hbentityOper;
	@Autowired
	private RelevanceProductService reProService;
	//是否处理明确状态的产品关联数据开关
	@Value("#{'${DealLinkProduct}'}")
	private boolean DealLinkProduct;
	
	@Async
	public String executeProcess(List<ConvertTask> taskList){
		for(ConvertTask task:taskList){
			if(!ruleUtil.hasTaskIDAndCity(task)){
				logger.error("Task任务："+task.getId()+"没有必要的taskID,CityCode");
				ruleUtil.updateTimerStatus(task, Constant.DATA_ERROR_STATE_CODE);
				continue;
			}
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("task_id", task.getTaskId());
			map.put("city_code", task.getGranularityValue());
			map.put("product_id", task.getProductId());
			try {
				//产品不做价格校验
				List<XCTicket_Commodity> commodityList = commodityService.getXCTicket_CommodityListByTaskID(map);
				List<XCTicket_CommodityDetail> commodityDetailList = detailService.getXCTicket_CommodityDetailListByID(map);
				//记录成功入库的商品
				List<XCTicket_CommodityDetail> checkedDoneList = new ArrayList<>();
				//遍历校验所有商品价格
				//价格防伪流程start
				//是否有新商品
				boolean hasNewCommodity = false;
				for(XCTicket_CommodityDetail item:commodityDetailList) {
					//商品价格有问题，忽略该商品
					if(!StringTools.isDoubleNumeric(item.getSale_price())){
						ruleUtil.insertLogMesg(task, null, item.getCommodity_id(), item.getCreate_time(), "商品价格异常", "");
						continue;
					}
					//当前商品rowkey
					String rowkey = RowkeyGenerator.generateCommodityRowkey(item.getCommodity_id(), item.getCreate_time(), item.getProduct_id());
					if(!StringTools.isNumeric(item.getCommodity_id())){
						ruleUtil.insertLogMesg(task, null, item.getCommodity_id(), item.getCreate_time(), "商品ID包含特殊字符", "");
						continue;
					}
					//商品类型不能为空
					if(item.getCommodity_type()==null || item.getCommodity_type().equals("")){continue;}
					//商品commodityType类型校验的开关： 可以让白名单内的类型通过；也可以指定黑名单
					String commodityTypeSwitch = configManager.getParamValue(Constant.XC_TICKET_GRAB, Constant.CPA_CONFIG_ENABLE_COMM_TYPE_SWITCH);
					if(commodityTypeSwitch.equals(Constant.CPA_CONFIG_ENABLE_COMM_TYPE)){
						String enableCommodityType = configManager.getParamValue(Constant.XC_TICKET_GRAB, Constant.CPA_CONFIG_ENABLE_COMM_TYPE);
						if(!enableCommodityType.contains(item.getCommodity_type())){
							continue;
						}
					}else if(commodityTypeSwitch.equals(Constant.CPA_CONFIG_ENABLE_COMM_TYPE_REFUSED)){
						String refusedCommodityType = configManager.getParamValue(Constant.XC_TICKET_GRAB, Constant.CPA_CONFIG_ENABLE_COMM_TYPE_REFUSED);
						if(refusedCommodityType.contains(item.getCommodity_type())){
							continue;
						}
					}
					/*
					 * 新数据 与 已存的商品数据，商品类型不一致时，忽略该条数据，确保同一商品ID数据库中只有一条数据
					*/
					XCTicketCommodityItem currentCommo = commodityItemsService.selectById(item.getCommodity_id(),item.getProduct_id());
					/*if(currentCommo != null && !item.getCommodity_type().equals(currentCommo.getCommodity_type())){
						//商品类型不一致。忽略
						continue;
					}*/
					boolean checkedDone = dataChecke(item,task);
					if(checkedDone){
						synchronized (RuleUtil.class) {
							ruleUtil.addTaskInfo(item.getTask_id(), item.getCreate_time(),Constant.XC_C_CODE,Constant.TICKE_BUS_TYPE,Constant.COMMODITY_LEVEL_TYPE);
						}
						checkedDoneList.add(item);
						if(currentCommo!=null){
							//优化代码健壮性，避免新抓取价格不存在，或者历史价格不存在情况
							if(StringTools.isValid(currentCommo.getSale_price()) && StringTools.isValid(item.getSale_price())){
								//当商品已存在，判断新抓取价格与历史价格是否相等，不相等意味着价格变动
								double historyPrice = Double.parseDouble(currentCommo.getSale_price());
								double currentPrice = Double.parseDouble(item.getSale_price());
								if(historyPrice!=currentPrice){
									currentCommo.setComm_price_change_num(currentCommo.getComm_price_change_num()+1);
									commodityItemsService.updateSelective(currentCommo);
								}
							}
							//抓取数据必须在最后操作，防止历史数据再覆盖回去
							item.setDetail_id(currentCommo.getId());
							commodityItemsService.update(item);
						}else{
							hasNewCommodity = true;
							//统一主键规则
							item.setDetail_id(rowkey);
							commodityItemsService.insert(item);
						}
						// 价格数据入价格历史表 start
						List<XCTicketCommodityPrice> priceList = null;
						if(item.getPrice_list_id()!=null && !item.getPrice_list_id().equals("")){
							priceList = commPriceService
									.queryPriceListByID(item.getPrice_list_id());
						}
						// 价格团期有数据，入价格团期数据
						if (priceList != null && priceList.size() > 0) {
							// rowkey生成规则 商品ID+售价日期+taskID
							hbentityOper.saveXCTicketCommoPriceByList(priceList, item.getCommodity_id(),
									Constant.TICKET_COMMODITY_PRICE_XC, Constant.HB_VARIABLE_FAMILY,item.getProduct_id());
						} else {
							// 价格团期数据不存在，存储当前商品价格数据
							hbentityOper.saveXCTicketCommoPrice(item.getTask_id(), item.getCreate_time(),
									item.getSale_price(), item.getCommodity_id(), Constant.TICKET_COMMODITY_PRICE_XC,
									Constant.HB_VARIABLE_FAMILY,item.getProduct_id());
						}
						// 价格数据入价格历史表 end
						hbentityOper.saveXCTicketCommodity(item, rowkey, Constant.TICKET_COMMODITY_H_XC, Constant.HB_VARIABLE_FAMILY);
					}else{
						//该商品价格校验失败，该条数据入log表
						commodityInsertLog(item, rowkey);
					}
				}
				//如果没有商品入库，忽略产品
				if(checkedDoneList.isEmpty()){
					ruleUtil.updateTimerStatus(task, Constant.DATA_SUCCESS_STATE_CODE);
					continue;
				}
				int commodityTypeNum = handleCommTypeNum(checkedDoneList);
				XCTicketProductItem param = handelProduct(checkedDoneList);
				param.setComm_type_num(commodityTypeNum);
				saveProductDirectly(commodityList,param,hasNewCommodity);
				ruleUtil.updateTimerStatus(task, Constant.DATA_SUCCESS_STATE_CODE);
				logger.info(">>>>>>当前线程："+Thread.currentThread().getId()+";XC_TICKET任务：["+task.getId()+"];执行完毕！<<<<<<");
			} catch (Exception e) {
				logger.error("XC_Ticket_Data_Process任务处理异常-------任务编码："+task.getId()+"---异常信息："+e.getMessage());
				ruleUtil.updateTimerStatus(task, Constant.DATA_ERROR_STATE_CODE);
			}
		}
		return null;
	}
	public String generateRowkey(String pro_goo_id, Date create_date, String TASKID){
		return RowkeyGenerator.generateRowkey(pro_goo_id, create_date, TASKID);
	}
	
	public boolean dataChecke(XCTicket_CommodityDetail item,ConvertTask convertTask){
		List<RuleLevelModel> rulelist = null;
		//考虑任务时间不等于抓取时间情况
		boolean needSuperRule = RuleUtil.needSuperRule(item.getCreate_time(),ruleUtil.getTicketSuperLevelList());
		//新抓取价格
		String priceStr = item.getSale_price();
		if(priceStr==null||priceStr.equals("")){
			priceStr = "0";
		}
		double price = Double.parseDouble(priceStr);
		if(needSuperRule){//走特殊防伪
			rulelist = ruleUtil.getTicketSuperLevelList();
		}else{
			rulelist = ruleUtil.getTicketNormalLevelList();
		}
		for(RuleLevelModel level:rulelist){
			List<Task_History> taskList = null;
			List<String> rowkeyList = null;
			int number = 0;
			double totalPrices = 0;
			double average = 0;
			double leftPrice = 0;
			double rightPrice = 0;
			if(needSuperRule){
				if(DateUtil.isRegionDate(item.getCreate_time(), level.getStart_date(), level.getEnd_date())){
					taskList = ruleUtil.getPartOfTask(level.getRule_level(), item.getCreate_time(),Constant.XC_C_CODE,Constant.TICKE_BUS_TYPE,Constant.COMMODITY_LEVEL_TYPE);
					if(taskList!=null){
						rowkeyList = new ArrayList<String>();
						for(Task_History task:taskList){
							rowkeyList.add(RowkeyGenerator.generateCommodityRowkey(item.getCommodity_id(), task.getCreate_Date(), item.getProduct_id()));
						}
						
					}
				}
			}else{
				taskList = ruleUtil.getPartOfTask(level.getRule_level(), item.getCreate_time(),Constant.XC_C_CODE,Constant.TICKE_BUS_TYPE,Constant.COMMODITY_LEVEL_TYPE);
				if(taskList != null && !taskList.isEmpty()){
					rowkeyList = new ArrayList<String>();
					for(Task_History task:taskList){
						rowkeyList.add(RowkeyGenerator.generateCommodityRowkey(item.getCommodity_id(), task.getCreate_Date(), item.getProduct_id()));
					}
				}
			}
			if(rowkeyList!=null){
				List<Map<String, String>> dataList = hBaseUtil
						.get(Constant.TICKET_COMMODITY_H_XC, Constant.HB_VARIABLE_FAMILY, rowkeyList);
				if(dataList.size()>0){
					for(Map<String, String> map:dataList){
						/*根据商品ID拿出所有批次的历史数据
						 * 考虑到存在不同产品ID会有相同商品ID的情况
						 * 在做校验时精确到产品ID和商品类别
						*/
						String currentProductId = map.get("product_id");
						String currentCommodityType = map.get("commodity_type");
						if (!map.isEmpty() && currentProductId!=null && currentProductId.equals(item.getProduct_id())
								&& currentCommodityType!=null && currentCommodityType.equals(item.getCommodity_type())) {
							String currentPrice = map.get("sale_price");
							if(currentPrice != null && !currentPrice.equals("")){
								totalPrices += Double.parseDouble(currentPrice);
								//避免task-date对应rowkey不存在数据的情况
								number++;
							}
						}
					}
					//因为hbase是通过商品ID拿数据的，存在不同产品的两个商品ID一致的情况
					if(number>0){
						average = totalPrices/number;
						leftPrice = ruleUtil.getLeftPrice(number, average, level.getLeft_value());
						rightPrice = ruleUtil.getRightPrice(number, average, level.getRight_value());
						//当价格超出容忍范围 记录日志
						if(price<leftPrice || price>rightPrice){
							try {
								ruleUtil.insertLogMesg(convertTask, null, item.getCommodity_id(), item.getCreate_time(), "价格超出容忍值范围[price="+price+"leftPrice="+leftPrice+";rightPrice="+rightPrice+"]", level.toString());
							} catch (Exception e) {
								logger.error("XC门票商品校验失败>>>"+item.getDetail_id());
							}
							//logger.warn("XC门票商品价格校验失败超出容忍阀值：taskID="+item.getTask_id()+";CommodityID="+item.getCommodity_id()+"ticket_cdetail_tc:["+item.getDetail_id()+"][price="+price+"leftPrice="+leftPrice+";rightPrice="+rightPrice+"]");
							return false;
						}
					}
				}
			}
		}
		return true;
	}
	/**
	 * 产品不做校验 直接入库
	 * 但要判断相对于上次抓取是否是新增产品
	 * 新增产品  入新产品表  入产品表   入产品历史表
	*/
	@Transactional
	public boolean saveProductDirectly(List<XCTicket_Commodity> commodityList,XCTicketProductItem param,boolean hasNewCommodity){
		//本次抓取产品的  rowkey  mysqlKey
		String currentRowKey = "";
		XCTicketProductItem xcProductItem = null;
		synchronized (XCTicketProductItemsService.class){
			for(XCTicket_Commodity item:commodityList) {
				ruleUtil.addTaskInfo(item.getTask_id(), item.getCreate_time(),Constant.XC_C_CODE,Constant.TICKE_BUS_TYPE,Constant.PRODUCT_LEVEL_TYPE);
				//当前product生成的rowkey
				currentRowKey = generateRowkey(item.getProduct_id(), item.getCreate_time(), item.getTask_id());
				//避免同一时刻跑同一个城市数据
				if(StringTools.isValid(item.getSnapshot_addr())){
					item.setSnapshot_addr(StringTools.getEndStringByChar(item.getSnapshot_addr(), "/"));
				}
				try {
					xcProductItem = productItemsService.selectById(item.getProduct_id());
					if(DealLinkProduct){
						dealLinkedProduct(item,xcProductItem,hasNewCommodity);
					}
					//所有数据都放在一个列族，实际上有两个列族（HB_VARIABLE_FAMILY HB_CONSTANT_FAMILY）
					if(xcProductItem==null){
						try {
							item.setDetail_id(currentRowKey);
							//新产品入产品表
							productNewService.insert(item);
							//入新产品表
							productItemsService.insert(item);
							//仅仅update产品分析相关的新增字段
							//当产品下不存在商品时，updateByItem会抛异常，更新失败，因为更新字段均为0
							param.setId(currentRowKey);
							productItemsService.updateByItem(param);
						} catch (Exception e) {
							logger.error("productItemsService>>>产品入库异常"+e.getMessage());
						}
					}else{
						//更新数据
						try {
							item.setDetail_id(xcProductItem.getId());
							productItemsService.update(item);
							//仅仅update产品分析相关的新增字段
							param.setId(xcProductItem.getId());
							productItemsService.updateByItem(param);
						} catch (Exception e) {
							logger.error("productItemsService>>>产品更新异常"+e.getMessage());
						}
					}
					//入历史表
					hbentityOper.saveXCTicketProduct(item, currentRowKey,Constant.TICKET_PRODUCT_H_XC, Constant.HB_VARIABLE_FAMILY,param);
				} catch (Exception e) {
					logger.error("productItemsService>>>产品查询异常>>>"+e.getMessage());
				}
				
			}
		}
		return true;
	}
	
	public int commodityInsertLog(XCTicket_CommodityDetail item,String rowkey){
		item.setDetail_id(rowkey);
		Map<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("detail_id", rowkey);
		try {
			List<XCTicket_CommodityDetail> list = detailService.queryLogByMap(paramMap);
			if(list.size()<=0){
				return detailService.insertCommodityDetailLog(item);
			}else{
				return 0;
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		
		return -1;
	}
	@Transactional
	public int dealLinkedProduct(XCTicket_Commodity item,XCTicketProductItem existProduct,boolean hasNewCommodity) {
		if(!StringTools.isValid(item.getLv_product_id())){
			return 0;
		}
		//对于已知关联关系的产品更新关联状态
		RelevanceProduct queryItem = reProService.viewRelevance(item.getLv_product_id(),Constant.TICKE_BUS_TYPE);
		RelevanceProduct newItem = new RelevanceProduct();
		if(existProduct!=null && existProduct.getIs_link()==1){
			if(hasNewCommodity && queryItem!=null && queryItem.getProdIdXC().equals(item.getProduct_id())){//如果新增商品且产品关联关系未改变
				//因为抓到新商品，所以状态更新，可以人工再做商品关联
				newItem.setIsDeal(0);
				reProService.updateRelevance(newItem);
			}
			return 0;
		}
		synchronized (RelevanceProductService.class) {
			newItem.setProdId(item.getLv_product_id());
			newItem.setProdIdXC(item.getProduct_id());
			newItem.setProdNameXC(item.getScenery_name());
			newItem.setBusinessCode(Constant.TICKE_BUS_TYPE);
			if(queryItem==null){
				reProService.insertXC(newItem);
				item.setIs_link(Constant.PRODUCT_IS_LINKED);
			}else if(queryItem.getProdIdXC()==null || queryItem.getProdIdXC().equals("")){
				reProService.updateXC(newItem);
				item.setIs_link(Constant.PRODUCT_IS_LINKED);
			}
		}
		return 1;
	}
	//计算产品下商品类别个数
	public int handleCommTypeNum(List<XCTicket_CommodityDetail> list){
		int commTypeNum = 0;
		Map<String,String> sb = new HashMap<>();
		for(XCTicket_CommodityDetail item:list){
			if(!sb.containsKey(item.getCommodity_type())){
				commTypeNum++;
				sb.put(item.getCommodity_type(), item.getCommodity_type());
			}
		}
		return commTypeNum;
	}
	
	private XCTicketProductItem handelProduct(List<XCTicket_CommodityDetail> checkedDoneList) {
		XCTicketProductItem item = new XCTicketProductItem();
		//优惠商品个数
		int commPreferentialNum = 0;
		//打包商品个数
		int commPackageNum = 0;
		String packageCommType = configManager.getParamValue(Constant.TICKET_COMMODITY_STARDARD_TYPE_CONFIG, Constant.TICKET_COMMODITY_STARDARD_TYPE_CONFIG);
		//设置产品对应商品的数量
		item.setCommodity_num(checkedDoneList.size());
		for(XCTicket_CommodityDetail commItem : checkedDoneList){
			if(StringTools.isValid(commItem.getPreferential())){commPreferentialNum++;}
			if(packageCommType.contains(";"+commItem.getCommodity_type().trim()+";")){commPackageNum++;}
		}
		item.setComm_preferential_num(commPreferentialNum);
		item.setComm_package_num(commPackageNum);
		return item;
	}
}
